The Look@NanoSIMS (short LANS) Matlab module written by Lubos Polerecky (Polerecky L., Adam B., Milucka J., Musat N., Vagner T. and Kuypers M. M. M. (2012) Look@NanoSIMS - a tool for the analysis of nanoSIMS data in environmental microbiology. Environ. Microbiol. 14, 1009–1023.) makes it easy to process NanoSIMS data and draw regions of interest (ROI). The lans2r package provides a convenient interface to import the ROI data generated by LANS into R for those interested in processing and plotting the data in R. This R markdown example demonstrates the basic functionality of the lans2r package. Please also consult the package help, e.g. ?load_LANS_summary.

Installation

You can install this package directly from GitHub using the devtools package.

install.packages("devtools")
library(devtools)
install_github('sebkopf/lans2r')

Load data

To load data into R, export it from LANS which creates a folder for each analysis with sub folders dat containing the aggregated information about the different ROIs (in text file format) and mat containing the raw ion maps (in Matlab file format). Both of these can be imported easily with this package. For easier demonstration lans2r bundles a set of 3 analyses (folders analysis1, analysis2 and analysis3) with the package sources.

library(lans2r)
folder <- system.file("extdata", "nanosims_data", package = "lans2r") # data base directory

ROI overview data

This loads the ROI overview data for the 3 analyses and assigns some additional information to the analyses (here rather random, column info). Since the parameters quiet=F indicates that information messages should be provided, it also outputs a summary of the loaded data.

data <- 
  load_LANS_summary (
    analysis = c("analysis1", "analysis2", "analysis3"), # the analysis folders
    base_dir = folder, # the data base director
    load_zstacks = T, # whether to load z-stacks as well (have to be exported from LANS!)
    info = c("turtle", "jetpack", "pizza"), # any additional information about the analyses
    quiet = F # output information about the files
  ) 
## INFO: folder '/Library/Frameworks/R.framework/Versions/3.2/Resources/library/lans2r/extdata/nanosims_data/analysis1/dat' read successfully.
##       Data for 37 ROIs with 4 ions recovered: 12C, 13C, 14N12C, 15N12C.
##       Z-stacks were loaded. Recovered 2 planes.
## INFO: folder '/Library/Frameworks/R.framework/Versions/3.2/Resources/library/lans2r/extdata/nanosims_data/analysis2/dat' read successfully.
##       Data for 33 ROIs with 4 ions recovered: 12C, 13C, 14N12C, 15N12C.
##       Z-stacks were loaded. Recovered 2 planes.
## INFO: folder '/Library/Frameworks/R.framework/Versions/3.2/Resources/library/lans2r/extdata/nanosims_data/analysis3/dat' read successfully.
##       Data for 34 ROIs with 4 ions recovered: 12C, 13C, 14N12C, 15N12C.
##       Z-stacks were loaded. Recovered 2 planes.

To calculate ratios and abundances, simply specificy which ions you would like to ratio. Note: for convenience, we make use of the pipe operator %>% for chaining multiple operations. For more information on the pipe, take a look at the magrittr package.

data <- data %>% 
  calculate_ratios(c("13C", "12C"), c("15N12C", "14N12C")) %>% # calculate isotope ratios
  calculate_abundances(c("13C", "12C"), c("15N12C", "14N12C")) # calculate abundances
## INFO: 624 isotope ratios + errors calculated and added to the data frame with data_type 'ratio'
##       ratios added (stored in 'variable' column): '13C/12C' (312x), '15N12C/14N12C' (312x)
## INFO: 624 isotope abundances + errors calculated and added to the data frame with data_type 'abundance'
##       fractional abundances added (stored in 'variable' column): '13C F' (312x), '15N12C F' (312x)

Overview

Let’s take a look at the first couple of rows of the data frame.

library(knitr)
data %>% head(n=10) %>% kable()
analysis info plane ROI data_type variable value sigma coord_x coord_y size pixels LW_ratio
analysis1 turtle all 1 ion_count 12C 1895850 1376.89869 17.38 192.93 0.83 353 2.45
analysis1 turtle all 2 ion_count 12C 1273919 1128.68020 18.39 175.25 0.75 290 1.57
analysis1 turtle all 3 ion_count 12C 1315417 1146.91630 40.38 168.26 0.70 250 1.66
analysis1 turtle all 4 ion_count 12C 1289955 1135.76186 42.05 207.80 0.72 267 2.16
analysis1 turtle all 5 ion_count 12C 1756159 1325.20149 42.92 147.66 0.81 334 2.50
analysis1 turtle all 6 ion_count 12C 1023934 1011.89624 46.56 103.93 0.67 232 2.11
analysis1 turtle all 7 ion_count 12C 5509 74.22264 52.29 22.77 1.32 893 1.09
analysis1 turtle all 8 ion_count 12C 1117870 1057.29372 61.77 120.06 0.62 195 2.39
analysis1 turtle all 9 ion_count 12C 1122839 1059.64098 63.38 146.02 0.65 217 2.02
analysis1 turtle all 10 ion_count 12C 1046665 1023.06647 74.39 98.29 0.66 221 2.23

Since this is now in long format so it’s easy to have both value and the sigma error, it’s hard to see line by line what is going on, let’s look just at analysis1 and recast the values into a wide format (using package tidyr but the older version reshape2 could achieve the same).

library(tidyr)
data %>% 
  filter(plane == "all", analysis == "analysis1") %>% 
  select(-data_type, -sigma) %>% 
  spread(variable, value) %>% 
  kable()
analysis info plane ROI coord_x coord_y size pixels LW_ratio 12C 13C 13C F 13C/12C 14N12C 15N12C 15N12C F 15N12C/14N12C
analysis1 turtle all 1 17.38 192.93 0.83 353 2.45 1895850 24315 1.2662974 0.0128254 7839685 115568 1.452726 0.0147414
analysis1 turtle all 2 18.39 175.25 0.75 290 1.57 1273919 16087 1.2470485 0.0126280 5625982 83997 1.471056 0.0149302
analysis1 turtle all 3 40.38 168.26 0.70 250 1.66 1315417 17084 1.2821004 0.0129875 5802914 87388 1.483591 0.0150593
analysis1 turtle all 4 42.05 207.80 0.72 267 2.16 1289955 16221 1.2418694 0.0125749 5773380 85690 1.462519 0.0148423
analysis1 turtle all 5 42.92 147.66 0.81 334 2.50 1756159 22267 1.2520622 0.0126794 7218762 107741 1.470565 0.0149251
analysis1 turtle all 6 46.56 103.93 0.67 232 2.11 1023934 13166 1.2695015 0.0128583 4434979 67186 1.492304 0.0151491
analysis1 turtle all 7 52.29 22.77 1.32 893 1.09 5509 75 1.3431232 0.0136141 51019 706 1.364911 0.0138380
analysis1 turtle all 8 61.77 120.06 0.62 195 2.39 1117870 13971 1.2343607 0.0124979 4858391 73758 1.495454 0.0151816
analysis1 turtle all 9 63.38 146.02 0.65 217 2.02 1122839 14201 1.2489446 0.0126474 4818643 70550 1.442978 0.0146411
analysis1 turtle all 10 74.39 98.29 0.66 221 2.23 1046665 13408 1.2648186 0.0128102 4484536 67210 1.476576 0.0149871
analysis1 turtle all 11 75.33 194.09 0.70 251 2.50 1474738 19091 1.2779910 0.0129454 5846622 87214 1.469774 0.0149170
analysis1 turtle all 12 81.03 80.98 0.66 224 2.10 1248264 15887 1.2567328 0.0127273 4733143 70559 1.468846 0.0149074
analysis1 turtle all 13 88.09 54.91 0.84 358 2.29 1800117 22854 1.2536678 0.0126958 7617556 114458 1.480313 0.0150256
analysis1 turtle all 14 92.22 120.89 0.47 115 1.63 568527 7220 1.2540230 0.0126995 2431404 36247 1.468887 0.0149078
analysis1 turtle all 15 103.21 191.31 0.71 261 2.45 1316299 16719 1.2542216 0.0127015 5354216 79383 1.460965 0.0148263
analysis1 turtle all 16 103.61 87.10 0.65 220 1.93 938611 11923 1.2543476 0.0127028 4648242 70254 1.488907 0.0151141
analysis1 turtle all 17 121.74 210.82 0.74 282 3.85 1362635 17326 1.2555427 0.0127151 5654394 84673 1.475379 0.0149747
analysis1 turtle all 18 124.16 187.82 0.75 290 1.79 1400489 17601 1.2411765 0.0125678 5719442 84978 1.464022 0.0148577
analysis1 turtle all 19 125.39 24.63 0.99 503 2.68 2361751 29706 1.2421716 0.0125780 10307418 153222 1.464748 0.0148652
analysis1 turtle all 20 127.43 164.74 0.79 320 2.17 1368881 17212 1.2417637 0.0125738 6086953 90474 1.464590 0.0148636
analysis1 turtle all 21 136.29 113.77 1.32 893 1.09 8054 87 1.0686648 0.0108021 62003 796 1.267536 0.0128381
analysis1 turtle all 22 140.19 223.32 0.85 370 3.50 1827876 23319 1.2596728 0.0127574 8116426 120857 1.467195 0.0148904
analysis1 turtle all 23 146.01 71.39 0.83 350 3.51 1679413 21240 1.2489320 0.0126473 6919252 102354 1.457701 0.0147926
analysis1 turtle all 24 164.97 228.62 0.73 274 1.76 1516371 19472 1.2678379 0.0128412 6036085 90507 1.477281 0.0149943
analysis1 turtle all 25 169.68 28.04 0.59 181 2.44 891849 11450 1.2675759 0.0128385 4044012 60265 1.468346 0.0149023
analysis1 turtle all 26 181.15 92.59 0.81 336 2.23 1638021 20747 1.2507475 0.0126659 6654647 97339 1.441635 0.0146272
analysis1 turtle all 27 183.90 67.12 0.91 424 4.13 2112810 26716 1.2486878 0.0126448 8551138 128144 1.476436 0.0149856
analysis1 turtle all 28 183.29 172.77 1.32 893 1.09 5741 60 1.0343044 0.0104511 50541 618 1.207999 0.0122277
analysis1 turtle all 29 184.37 29.74 0.60 186 2.53 1020716 12973 1.2550196 0.0127097 4584436 68528 1.472782 0.0149480
analysis1 turtle all 30 190.63 16.30 0.72 266 2.68 1334489 16868 1.2482268 0.0126400 6013066 91080 1.492101 0.0151470
analysis1 turtle all 31 196.02 117.40 0.84 365 3.47 1786621 22397 1.2380750 0.0125360 8040776 120772 1.479768 0.0150199
analysis1 turtle all 32 205.67 54.95 0.62 196 1.74 791714 9750 1.2165238 0.0123151 3622960 52959 1.440701 0.0146176
analysis1 turtle all 33 219.40 141.15 0.94 457 2.81 1862303 23685 1.2558404 0.0127181 8984273 129486 1.420775 0.0144125
analysis1 turtle all 34 225.73 68.66 0.73 273 2.32 1259561 15944 1.2500147 0.0126584 5258553 76265 1.429571 0.0145030
analysis1 turtle all 35 230.29 107.77 1.32 893 1.09 9820 125 1.2569130 0.0127291 85665 1087 1.252997 0.0126890
analysis1 turtle all 36 238.29 25.77 1.32 893 1.09 9279 89 0.9500427 0.0095916 89258 1116 1.234868 0.0125031
analysis1 turtle all 37 246.95 68.93 0.61 188 1.76 899748 11237 1.2335000 0.0124891 4060267 60101 1.458632 0.0148022

Plotting

Plot all the data using the ggplot package.

library(ggplot2)
data %>% 
  ggplot() +
  aes(size, value, color = paste(analysis, info), shape = plane) + 
  geom_errorbar(aes(ymin = value - 2*sigma, ymax = value + 2*sigma), colour="black", width = 0) +
  geom_point(size=3) + 
    labs(x = expression("ROI size ["*mu*"m"^2*"]"), y="", 
         title = expression("ROI summary (2"*sigma*" error bars, may be smaller than symbols)"),
         color = "Analysis") + 
  facet_wrap(~variable, scales="free", nrow = 2) + 
  theme_bw()

Focus in on the combined counts (not the individual planes from the z-stack) and look just at ratios:

last_plot() %+% (data %>% filter(plane == "all", data_type == "ratio"))

Ion maps

Again, loading the ion maps for all 3 analyses.

maps <- 
  load_LANS_maps (
    analysis = c("analysis1", "analysis2", "analysis3"),
    base_dir = folder
  ) 
## INFO: folder '/Library/Frameworks/R.framework/Versions/3.2/Resources/library/lans2r/extdata/nanosims_data/analysis1/mat' read successfully.
##       Ion map data for 256 x 256 pixel frame (10.014 microm^2) for 4 ions recovered: 12C, 13C, 14N12C, 15N12C.
##       37 ROIs identified in the frame.
## INFO: folder '/Library/Frameworks/R.framework/Versions/3.2/Resources/library/lans2r/extdata/nanosims_data/analysis2/mat' read successfully.
##       Ion map data for 256 x 256 pixel frame (10.014 microm^2) for 4 ions recovered: 12C, 13C, 14N12C, 15N12C.
##       33 ROIs identified in the frame.
## INFO: folder '/Library/Frameworks/R.framework/Versions/3.2/Resources/library/lans2r/extdata/nanosims_data/analysis3/mat' read successfully.
##       Ion map data for 256 x 256 pixel frame (10.014 microm^2) for 4 ions recovered: 12C, 13C, 14N12C, 15N12C.
##       34 ROIs identified in the frame.

The data in these looks similar to the summary data frame except that it is broken out pixel by pixel:

maps %>% head(n=10) %>% kable()
analysis x.px y.px frame_size.px x.um y.um frame_size.um variable data_type value sigma ROI
analysis1 1 1 256 0.0391172 0.0391172 10.014 12C ion_count 1721 41.48494 0
analysis1 1 2 256 0.0391172 0.0782344 10.014 12C ion_count 1694 41.15823 0
analysis1 1 3 256 0.0391172 0.1173516 10.014 12C ion_count 1508 38.83298 0
analysis1 1 4 256 0.0391172 0.1564688 10.014 12C ion_count 1297 36.01389 0
analysis1 1 5 256 0.0391172 0.1955859 10.014 12C ion_count 1136 33.70460 0
analysis1 1 6 256 0.0391172 0.2347031 10.014 12C ion_count 786 28.03569 0
analysis1 1 7 256 0.0391172 0.2738203 10.014 12C ion_count 702 26.49528 0
analysis1 1 8 256 0.0391172 0.3129375 10.014 12C ion_count 453 21.28380 0
analysis1 1 9 256 0.0391172 0.3520547 10.014 12C ion_count 319 17.86057 0
analysis1 1 10 256 0.0391172 0.3911719 10.014 12C ion_count 220 14.83240 0

To make it easier to plot these kind of maps, lans2r provides a convenience functoin plot_maps but of course this could be adjusted as needed (look at the source code to see how this one is made). By default ion counts are normalized for each ion so they can be visualized on the same scale.

plot_maps(maps)

Focusing in on just one ion, we can ditch the normalization, and let’s also not draw ROIs for a direct look. Also, because it’s a ggplot, all ggplot modifications of the plot are fair game.

plot_maps(maps %>% filter(variable == "14N12C", analysis %in% c("analysis1", "analysis2")), 
          normalize = FALSE, draw_ROIs = FALSE) + 
  theme(legend.position = "right") + labs(fill = "ion count")

Future directions

Note that for plotting maps, lans2r does not (yet) support any smoothing so although the plot_maps function theoretically supports plotting ratios and abundances as well (which can be calculated from the maps data the same way using calculate_ratios and calculate_abundances), in practice this does not work so well because individual pixels often have extreme values offsetting proper scaling. This might be part of future expansions if the package sees a lot of use so please email with suggestions if you find it helpful.